﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Dolinay;
using System.Management;
using System.Management.Instrumentation;
using System.IO;
using System.Xml.Serialization;


using USBDrive;
using FileCopier;
using Settings;


namespace MASSBAckUp
{
    public partial class MainForm : Form, SettingsUpdater
    {
        private DriveDetector driveDetector = null;

        AppSettings settings;

        private const String SettingsFileName = "settings.xml";

        public MainForm()
        {
            settings = new AppSettings(this);
            InitializeComponent();
            driveDetector = new DriveDetector();
            driveDetector.DeviceArrived += new DriveDetectorEventHandler(
                OnDriveArrived);
            driveDetector.DeviceRemoved += new DriveDetectorEventHandler(
                OnDriveRemoved);
            driveDetector.QueryRemove += new DriveDetectorEventHandler(
                OnQueryRemove);
        }

        public delegate void SettingsDelegate();

        public void SettingWasUpdated()
        {
            SettingsDelegate d = new SettingsDelegate(SettingsWorker);
            this.BeginInvoke(d);

        }


        private void SettingsWorker()
        {
            DeviceList.Items.Clear();
            foreach (Object ob in settings.devices)
            {
                MassStorageDevice dv = (MassStorageDevice)ob;
                int indx = DeviceList.Items.Add(dv);
                DeviceList.SetItemChecked(indx, !dv.Ignore);
            }
        }

        // Called by DriveDetector when removable device in inserted

        public delegate void DelegateDriveFound(String a);

        private void OnDriveArrived(object sender, DriveDetectorEventArgs e)
        {
            
            // e.Drive is the drive letter, e.g. "E:\\"

            // If you want to be notified when drive is being removed (and be

            // able to cancel it),

            // set HookQueryRemove to true

            e.HookQueryRemove = true;

            DelegateDriveFound gdi = new DelegateDriveFound(this.DriveFound);
            IAsyncResult result = gdi.BeginInvoke(e.Drive.Substring(0, 1), null, this);
            gdi.EndInvoke(result);

            //String Serial = driveNameToSerial.getSerialNumberFromDriveLetter("G:\\");
        }

        void DriveFound(String DriverLetter)
        {

            USBDriveInfo Info = USBDriveInfoCap.getSerialNumberFromDriveLetter(DriverLetter);

            MassStorageDevice chk = new MassStorageDevice();
            chk.SerialNumber = Info.SerialNumber;
            chk.Name = Info.Caption;
            chk.ActualDiskLetter = DriverLetter;
            chk.IsOnline = true;
            //Check that we know this device:
            if (!settings.devices.Contains(chk))
            {
                NewDeviceSettings ds = new NewDeviceSettings();
                ds.SetCaption(chk.Name);
                if (ds.ShowDialog() == DialogResult.OK)
                {
                    switch (ds.ResAction)
                    {
                        case NewDeviceSettings.Action.SetUp:
                            {

                            }break;
                        default:
                            {
                                chk.Ignore = true;
                                settings.devices.Add(chk);
                                settings.devices.Sort();
                                settings.Save(SettingsFileName);
                                settings.Update();
                            }break;
                    }
                }
            }
            else
            {
                int indx = settings.devices.BinarySearch(chk);
                chk = (MassStorageDevice) settings.devices[indx];
                chk.ActualDiskLetter = DriverLetter;
                chk.IsOnline = true;
                settings.Update();

                if (!chk.Ignore)
                {
                    CopyForm cf = new CopyForm(chk);
                    cf.ShowDialog();
                }
            }

        }

        // Called by DriveDetector after removable device has been unplugged

        private void OnDriveRemoved(object sender, DriveDetectorEventArgs e)
        {
            // TODO: do clean up here, etc. Letter of the removed drive is in

            // e.Drive;
            DelegateDriveFound gdi = new DelegateDriveFound(this.DriveWasRemoved);
            IAsyncResult result = gdi.BeginInvoke(e.Drive.Substring(0, 1), null, this);
            gdi.EndInvoke(result);
        }

        private void DriveWasRemoved(String DriverLetter)
        {
            MassStorageDevice chk = null;

            foreach (Object ob in settings.devices)
            {
                chk = (MassStorageDevice) ob;
                if (chk.ActualDiskLetter == DriverLetter) break;
                chk = null;
            }


            if(chk != null)
            {
                chk.IsOnline = false;
                chk.ActualDiskLetter = @"";
                settings.Update();
            }
        }

        // Called by DriveDetector when removable drive is about to be removed

        private void OnQueryRemove(object sender, DriveDetectorEventArgs e)
        {
            // Should we allow the drive to be unplugged?

            if (MessageBox.Show("Allow remove?", "Query remove",
                MessageBoxButtons.YesNo, MessageBoxIcon.Question) ==
                    DialogResult.Yes)
                e.Cancel = false;        // Allow removal

            else
                e.Cancel = true;         // Cancel the removal of the device

        }



        private void CloseButton_Click(object sender, EventArgs e)
        {
            //CloseAndSaveSettings();
            Close();
        }

        private void CloseAndSaveSettings()
        {
            try
            {
                settings.Save(SettingsFileName);
            }
            catch (Exception /*Excp*/)
            {
            }
            Close();
        }




        private void MainForm_Load(object sender, EventArgs e)
        {
            try
            {
                settings = AppSettings.Load(SettingsFileName, this);
                List<USBDriveInfo> drives = USBDriveInfoCap.enumerateConnectedDevices();
                foreach (USBDriveInfo Info in drives)
                {
                    MassStorageDevice chk = new MassStorageDevice();
                    chk.SerialNumber = String.Copy(Info.SerialNumber);
                    chk.Name = String.Copy(Info.Caption);
                    int indx = settings.devices.BinarySearch(chk);
                    if (indx >= 0)
                    {
                        chk = (MassStorageDevice) settings.devices[indx];
                        chk.IsOnline = true;
                        chk.ActualDiskLetter = Info.DriverLetter.Substring(0, 1);
                    }
                }
                settings.Update();
            }
            catch (Exception /*Excp*/)
            {
            }
        }

        private void DeviceList_SelectedIndexChanged(object sender, EventArgs e)
        {
            ListBox lb = (ListBox) sender;
            if (lb.SelectedIndex >= 0)
            {
                DeviceSelected(lb.SelectedIndex);
            }
            else
            {
               NoDeviceSelected();
            }

        }

        private void DeviceSelected(int Index)
        {
            DeleteDeviceButton.Enabled = true;
            SetUpDeviceButton.Enabled = true;
            MassStorageDevice dv = (MassStorageDevice) settings.devices[Index];
            if (dv != null && dv.IsOnline)
            {
                SyncButton.Enabled = true;
            }
            else
            {
                SyncButton.Enabled = false;
            }
        }

        private void NoDeviceSelected()
        {
            DeleteDeviceButton.Enabled = false;
            SetUpDeviceButton.Enabled = false;
            SyncButton.Enabled = false;
        }

        private void DeleteDeviceButton_Click(object sender, EventArgs e)
        {
            if (DeviceList.SelectedIndex >= 0)
            {
                MassStorageDevice dv = (MassStorageDevice) DeviceList.Items[DeviceList.SelectedIndex];
                if (System.Windows.Forms.MessageBox.Show(
                    "Вы действительно хотите удалить натсройки\nдля устройства:\n" + dv.Name + " (" + dv.SerialNumber + ") ?", "Удаление настроек...",
                    System.Windows.Forms.MessageBoxButtons.YesNo,
                    System.Windows.Forms.MessageBoxIcon.Warning) ==
                    System.Windows.Forms.DialogResult.Yes)
                {
                    settings.devices.Remove(dv);
                    settings.Save(SettingsFileName);
                    settings.Update();
                }
            }
        }

        private void SetUpDeviceButton_Click(object sender, EventArgs e)
        {
            if (DeviceList.SelectedIndex >= 0)
            {
                MassStorageDevice dv = (MassStorageDevice) DeviceList.Items[DeviceList.SelectedIndex];
                DeviceSettings frm = new DeviceSettings(dv);
                if (frm.ShowDialog() == DialogResult.OK)
                {
                    settings.Save(SettingsFileName);
                }
            }
        }

        private void DeviceList_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            MassStorageDevice dv = (MassStorageDevice) DeviceList.Items[e.Index];
            dv.Ignore = (e.NewValue != CheckState.Checked);
            settings.Save(SettingsFileName);
        }

        private void MainForm_Resize(object sender, EventArgs e)
        {
            if (FormWindowState.Minimized == WindowState)
                Hide();
        }

        private void TrayIcon_DoubleClick(object sender, EventArgs e)
        {
            Show();
            WindowState = FormWindowState.Normal;
        }


        private void SyncButton_Click(object sender, EventArgs e)
        {
            int indx = DeviceList.SelectedIndex;
            if (indx >= 0)
            {
                MassStorageDevice dv = (MassStorageDevice)DeviceList.Items[indx];
                if (dv.IsOnline)
                {
                    CopyForm cf = new CopyForm(dv);
                    cf.ShowDialog();
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ;
        }

        private void button2_Click(object sender, EventArgs e)
        {
           
        }
    }


}
